package com.wangshuqi.ftp.intergration;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.*;
import java.nio.charset.StandardCharsets;

@Component
@ConfigurationProperties(prefix = "ftp")
public class FTPClientTemplate {

    private static final Logger logger = LoggerFactory.getLogger(FTPClientTemplate.class);
    private String hostname; // 机器的ip
    private int port; // 端口号：21
    private String username; // 账号
    private String password; // 密码
    private String savePath; // 存储的位置

    private FTPClient ftpClient;

    /**
     * 登录ftp连接
     *
     * @param
     * @return void
     * @author codewsq
     * @date 2022/9/18 0018 17:57
     */
    public boolean loginConnection() {
        ftpClient = new FTPClient();
        try {
            // 设置连接机器
            ftpClient.connect(hostname, port);
            ftpClient.login(username, password);
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                logger.info("ftp连接失败");
                ftpClient.disconnect(); // 断开连接
                return false;
            }
            // 将文件类型设置成二进制
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            // 创建要存储文件夹的目录: 主要目录只能一级一级创建，不能一次创建多层; 在 选择创建目录是一定要看是否有写权限，不然失败
            ftpClient.makeDirectory(savePath);
            // 改变默认存放的位置
            ftpClient.changeWorkingDirectory(savePath);
            //开启被动模式，否则文件上传不成功，也不报错
            ftpClient.enterLocalPassiveMode();
            return true;
        } catch (IOException e) {
            logger.error(e.getMessage());
        }
        return false;
    }

    /**
     * 上传文件至ftp服务器
     *
     * @param uploadFile 上传的文件
     * @return void
     * @author codewsq
     * @date 2022/9/17 0017 22:16
     */
    public boolean uploadFile(String uploadFile) {
        if (!this.loginConnection()) {
            return false;
        }
        boolean result = false;
        InputStream inputStream = null;
        try {
            File file = new File(uploadFile);
            if (file.isDirectory()) {
                logger.info("uploadFile不是文件");
                return false;
            }
            inputStream = new FileInputStream(file);
            String fileName = new String(file.getName().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            result = ftpClient.storeFile(fileName, inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            this.disconnect();
        }
        return result;
    }

    /**
     * ftp文件下载
     *
     * @param savePath 文件保存路径
     * @param fileName 文件下载名称
     * @return void
     * @author codewsq
     * @date 2022/9/17 0017 22:13
     */
    public boolean downloadFile(String savePath, String fileName) {
        if (!this.loginConnection()) {
            return false;
        }
        boolean result = false;
        String name = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        OutputStream outputStream = null;
        try {
            FTPFile[] ftpFiles = ftpClient.listFiles();
            for (FTPFile ftpFile : ftpFiles) {
                if (name.equals(ftpFile.getName())) {
                    File file = new File(savePath + fileName);
                    outputStream = new FileOutputStream(file);
                    result = ftpClient.retrieveFile(ftpFile.getName(), outputStream);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            this.disconnect();
        }
        return result;
    }

    /**
     * ftp服务器断开连接
     *
     * @return void
     * @author codewsq
     * @date 2022/9/18 0018 17:52
     */
    public void disconnect() {
        if (ftpClient == null) {
            return;
        }
        try {
            ftpClient.logout();
            ftpClient.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void setHostname(String hostname) {
        this.hostname = hostname;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setSavePath(String savePath) {
        this.savePath = savePath;
    }
}
